﻿
/* ==============================================================================
*
*   Copyright (c) 2010, Pierre Favier
*   All rights reserved.
*
*   NTasking is free software: you can redistribute it and/or modify it
*   under the terms of the GNU General Public License as published by the
*   Free Software Foundation.
*
*   Redistribution and use in source and binary forms, with or without
*   modification, are permitted provided that the following conditions
*   are met:
*
*   -   Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*
*   -   Redistributions in binary form must reproduce the above
*       copyright notice, this list of conditions and the following
*       disclaimer in the documentation and/or other materials
*       provided with the distribution.
*
*   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
*   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
*   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
*   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
*   BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
*   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
*   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
*   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
*   TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
*   THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
*   SUCH DAMAGE.
*
* ============================================================================== */

using System;
using NUnit.Framework;
using Rhino.Mocks;

namespace NTasking.ValidationTests.Other.Capacities
{

    [TestFixture]
    public class Protected : ValidationTest
    {
                
        internal class Protected0 : ValidationTestProtected
        {

            [Entry]
            internal Action Put { get; private set; }
            [Entry]
            internal Func<bool> Get { get; private set; }
            [Entry]
            internal ActionFamily<double> FPut { get; private set; }
            [Entry]
            internal FuncFamily<double, bool> FGet { get; private set; }
            [ReadOnlyOperation]
            internal Func<bool> ROGet { get; private set; }
            [ReadWriteOperation]
            internal Func<bool> RWGet { get; private set; }
            [ReadWriteOperation]
            internal Action RWPut { get; private set; }


            internal Protected0(IValidationTestResult result)
                : base(result)
            {
                Entry(Put, () => true, () => { });

                Entry(Get, () => true, () => { return true; });

                Entry(FPut, (i) => true, (i) => { });

                Entry(FGet, (i) => true, (i) => { return true; });

                Entry(FPut, () => true, (i) => { });

                Entry(FGet, () => true, (i) => { return true; });

                ReadWriteOperation(RWPut, () => { });

                ReadWriteOperation(RWGet, () => { return true; });

                ReadOnlyOperation(ROGet, () => { return true; });
            }

        }
        
                
        internal class Protected1 : ValidationTestProtected
        {

            [Entry]
            internal Action<int> Put { get; private set; }
            [Entry]
            internal Func<int, bool> Get { get; private set; }
            [Entry]
            internal ActionFamily<double, int> FPut { get; private set; }
            [Entry]
            internal FuncFamily<double, int, bool> FGet { get; private set; }
            [ReadOnlyOperation]
            internal Func<int, bool> ROGet { get; private set; }
            [ReadWriteOperation]
            internal Func<int, bool> RWGet { get; private set; }
            [ReadWriteOperation]
            internal Action<int> RWPut { get; private set; }


            internal Protected1(IValidationTestResult result)
                : base(result)
            {
                Entry(Put, () => true, (p1) => { });

                Entry(Get, () => true, (p1) => { return true; });

                Entry(FPut, (i) => true, (i, p1) => { });

                Entry(FGet, (i) => true, (i, p1) => { return true; });

                Entry(FPut, () => true, (i, p1) => { });

                Entry(FGet, () => true, (i, p1) => { return true; });

                ReadWriteOperation(RWPut, (p1) => { });

                ReadWriteOperation(RWGet, (p1) => { return true; });

                ReadOnlyOperation(ROGet, (p1) => { return true; });
            }

        }
        
                
        internal class Protected2 : ValidationTestProtected
        {

            [Entry]
            internal Action<int, int> Put { get; private set; }
            [Entry]
            internal Func<int, int, bool> Get { get; private set; }
            [Entry]
            internal ActionFamily<double, int, int> FPut { get; private set; }
            [Entry]
            internal FuncFamily<double, int, int, bool> FGet { get; private set; }
            [ReadOnlyOperation]
            internal Func<int, int, bool> ROGet { get; private set; }
            [ReadWriteOperation]
            internal Func<int, int, bool> RWGet { get; private set; }
            [ReadWriteOperation]
            internal Action<int, int> RWPut { get; private set; }


            internal Protected2(IValidationTestResult result)
                : base(result)
            {
                Entry(Put, () => true, (p1, p2) => { });

                Entry(Get, () => true, (p1, p2) => { return true; });

                Entry(FPut, (i) => true, (i, p1, p2) => { });

                Entry(FGet, (i) => true, (i, p1, p2) => { return true; });

                Entry(FPut, () => true, (i, p1, p2) => { });

                Entry(FGet, () => true, (i, p1, p2) => { return true; });

                ReadWriteOperation(RWPut, (p1, p2) => { });

                ReadWriteOperation(RWGet, (p1, p2) => { return true; });

                ReadOnlyOperation(ROGet, (p1, p2) => { return true; });
            }

        }
        
                
        internal class Protected3 : ValidationTestProtected
        {

            [Entry]
            internal Action<int, int, int> Put { get; private set; }
            [Entry]
            internal Func<int, int, int, bool> Get { get; private set; }
            [Entry]
            internal ActionFamily<double, int, int, int> FPut { get; private set; }
            [Entry]
            internal FuncFamily<double, int, int, int, bool> FGet { get; private set; }
            [ReadOnlyOperation]
            internal Func<int, int, int, bool> ROGet { get; private set; }
            [ReadWriteOperation]
            internal Func<int, int, int, bool> RWGet { get; private set; }
            [ReadWriteOperation]
            internal Action<int, int, int> RWPut { get; private set; }


            internal Protected3(IValidationTestResult result)
                : base(result)
            {
                Entry(Put, () => true, (p1, p2, p3) => { });

                Entry(Get, () => true, (p1, p2, p3) => { return true; });

                Entry(FPut, (i) => true, (i, p1, p2, p3) => { });

                Entry(FGet, (i) => true, (i, p1, p2, p3) => { return true; });

                Entry(FPut, () => true, (i, p1, p2, p3) => { });

                Entry(FGet, () => true, (i, p1, p2, p3) => { return true; });

                ReadWriteOperation(RWPut, (p1, p2, p3) => { });

                ReadWriteOperation(RWGet, (p1, p2, p3) => { return true; });

                ReadOnlyOperation(ROGet, (p1, p2, p3) => { return true; });
            }

        }
        
                
        internal class Protected4 : ValidationTestProtected
        {

            [Entry]
            internal Action<int, int, int, int> Put { get; private set; }
            [Entry]
            internal Func<int, int, int, int, bool> Get { get; private set; }
            [Entry]
            internal ActionFamily<double, int, int, int, int> FPut { get; private set; }
            [Entry]
            internal FuncFamily<double, int, int, int, int, bool> FGet { get; private set; }
            [ReadOnlyOperation]
            internal Func<int, int, int, int, bool> ROGet { get; private set; }
            [ReadWriteOperation]
            internal Func<int, int, int, int, bool> RWGet { get; private set; }
            [ReadWriteOperation]
            internal Action<int, int, int, int> RWPut { get; private set; }


            internal Protected4(IValidationTestResult result)
                : base(result)
            {
                Entry(Put, () => true, (p1, p2, p3, p4) => { });

                Entry(Get, () => true, (p1, p2, p3, p4) => { return true; });

                Entry(FPut, (i) => true, (i, p1, p2, p3, p4) => { });

                Entry(FGet, (i) => true, (i, p1, p2, p3, p4) => { return true; });

                Entry(FPut, () => true, (i, p1, p2, p3, p4) => { });

                Entry(FGet, () => true, (i, p1, p2, p3, p4) => { return true; });

                ReadWriteOperation(RWPut, (p1, p2, p3, p4) => { });

                ReadWriteOperation(RWGet, (p1, p2, p3, p4) => { return true; });

                ReadOnlyOperation(ROGet, (p1, p2, p3, p4) => { return true; });
            }

        }
        
        
        [Test]
        public void Test()
        {
            Protected0 protected0 = null;
            Protected1 protected1 = null;
            Protected2 protected2 = null;
            Protected3 protected3 = null;
            Protected4 protected4 = null;
            IValidationTestResult result = Mocks.DynamicMock<IValidationTestResult>();

            Ada.Declare(() =>
            {
                protected0 = new Protected0(result);
                protected1 = new Protected1(result);
                protected2 = new Protected2(result);
                protected3 = new Protected3(result);
                protected4 = new Protected4(result);
                
                // Setup text expectations

                Expect.Call(result.TestFailed).Repeat.Never();

                Mocks.ReplayAll();
            },
            Begin: () =>
            {
                // Start test execution
                
                protected0.Put();
                protected1.Put(1);
                protected2.Put(1, 2);
                protected3.Put(1, 2, 3);
                protected4.Put(1, 2, 3, 4);
                
                protected0.Get();
                protected1.Get(1);
                protected2.Get(1, 2);
                protected3.Get(1, 2, 3);
                protected4.Get(1, 2, 3, 4);
                
                protected0.FPut[0.0]();
                protected1.FPut[0.0](1);
                protected2.FPut[0.0](1, 2);
                protected3.FPut[0.0](1, 2, 3);
                protected4.FPut[0.0](1, 2, 3, 4);
                
                protected0.FGet[0.0]();
                protected1.FGet[0.0](1);
                protected2.FGet[0.0](1, 2);
                protected3.FGet[0.0](1, 2, 3);
                protected4.FGet[0.0](1, 2, 3, 4);
                
                protected0.RWPut();
                protected1.RWPut(1);
                protected2.RWPut(1, 2);
                protected3.RWPut(1, 2, 3);
                protected4.RWPut(1, 2, 3, 4);
                
                protected0.RWGet();
                protected1.RWGet(1);
                protected2.RWGet(1, 2);
                protected3.RWGet(1, 2, 3);
                protected4.RWGet(1, 2, 3, 4);
                
                protected0.ROGet();
                protected1.ROGet(1);
                protected2.ROGet(1, 2);
                protected3.ROGet(1, 2, 3);
                protected4.ROGet(1, 2, 3, 4);
                
            });
        }

    }

}
